import datetime
from datetime import timedelta, date
from django.db.models import Q, Count, F, Sum
from django.db.models.functions import ExtractMonth
from rest_framework import viewsets, status, views
from rest_framework.decorators import action
from rest_framework.response import Response
from custom.pagination import MyPageNumberPagination
from system.models import Dept

from .serializers import *


class DashboardView(views.APIView):
    '''首页数据'''

    def get(self, request):
        # 患者总人数
        patient_total = Patient.objects.all().count()

        # 报告总数
        report_total = Report.objects.all().count()

        # 学校总数
        school_total = Dept.objects.filter(dept_type=0).count()

        # 医院总数
        hospital_total = Dept.objects.filter(dept_type=1).count()

        # 今年增长曲线
        year_count = Report.objects.filter(create_time__year__gte=datetime.now().year) \
            .annotate(month=ExtractMonth('create_time')) \
            .values('month').order_by('month') \
            .annotate(num=Count('pk')).values_list('month', 'num')
        year_count = {
            'month': [str(i[0]) + '月' for i in year_count],
            'data': [i[1] for i in year_count],
        }

        data = {
            'yearCount': year_count,
            'patientTotal': patient_total,
            'reportTotal': report_total,
            'hospitalTotal': hospital_total,
            'schoolTotal': school_total,
        }
        return Response(data)


class ReportManageAnalysisView(views.APIView):
    '''筛查报告昨日新增报告总数和复查初筛占比数据'''

    def get(self, request):
        yesterday = date.today() - timedelta(days=1)

        yesterday_reports = Report.objects.filter(create_time__gte=yesterday)


        # 昨日新增报告总数
        yesterday_report_total = yesterday_reports.count()

        print(yesterday,yesterday_report_total)

        # 昨日新增报告总数
        total = yesterday_reports.values('report_type').order_by('report_type').annotate(value=Count('report_type'))
        report_type_count = []
        for i in total:
            if i.get('report_type') == 0:
                report_type_count.append({'name': '初筛', 'value': i.get('value')})
            elif i.get('report_type') == 1:
                report_type_count.append({'name': '复测', 'value': i.get('value')})

        data = {
            'yesterdayTotal': yesterday_report_total,
            'reportTypeCount': report_type_count,

        }
        return Response(data)


class AnalysisView(views.APIView):
    '''大数据面板数据'''

    def get(self, request):
        # 计划人数
        total_batch = self.get_batch_total()

        # 筛查人数
        total_screen = self.get_screen_total()

        # 患者男女数量
        sex_total = self.get_sexual_total()

        # 各类学校总数
        school_count, schoolPieData = self.get_stage_distribution()

        # 近半年增长曲线
        year_count = self.get_annual_growth()

        report_list = Report.objects.filter(OS_VASC__isnull=False, OD_VASC__isnull=False).order_by('create_time')

        # 近视男女数据
        myopia_data = self.get_myopia_data(report_list)

        # 各学段的近视人数
        stage_data = self.get_stage_myopia(report_list)

        # 近视排行榜
        school_sort = self.get_school_sort(report_list)

        # 地图值
        guangzhou = self.get_map_data(report_list)

        data = {
            'batchTotal': total_batch.get('total'),
            'screenTotal': total_screen,
            'sexTotal': sex_total,
            'schoolPieData': schoolPieData,
            'schoolCount': school_count,
            'yearCount': year_count,
            'myopiaData': myopia_data,
            'stageData': stage_data,
            'schoolSort': school_sort,
            'mapData': guangzhou,
        }
        return Response(data, status=status.HTTP_200_OK)

    def get_batch_total(self):
        # 计划人数
        total_batch = Batch.objects.aggregate(total=Sum('total'))
        return total_batch

    def get_screen_total(self):
        # 筛查人数
        total_screen = Report.objects.values('patient', 'batch').distinct().count()
        return total_screen

    def get_sexual_total(self):
        # 患者男女数量
        sexual_total = Patient.objects.values('gender').order_by('gender').annotate(total=Count('gender'))
        sex_total = []
        for index in sexual_total:
            if index.get('gender') == 1:
                sex_total.append({
                    'name': '男',
                    'value': index.get('total')
                })

            if index.get('gender') == 2:
                sex_total.append({
                    'name': '女',
                    'value': index.get('total')
                })
        return sex_total

    def get_annual_growth(self):
        # 当年增长变化
        year_count = Report.objects.filter(create_time__year__gte=datetime.now().year) \
            .annotate(month=ExtractMonth('create_time')) \
            .values('month').order_by('month') \
            .annotate(count=Count('pk'))\
            .values_list('month', 'count')
        year_count = {
            'month': [str(i[0]) + '月' for i in year_count],
            'count': [i[1] for i in year_count],
        }
        return year_count

    def get_school_sort(self, report_list):
        # 近视前10学校排行榜
        school_sort = report_list.filter(Q(OS_VASC__lt=5.0) | Q(OD_VASC__lt=5.0))\
                          .values('batch__school') \
                          .order_by('batch__school')\
                          .annotate(school=F('batch__school__name')) \
                          .annotate(count=Count('batch__school'))\
                          .values('school', 'count')[:10]
        for index, item in enumerate(school_sort):
            school_sort[index]['percentage'] = round(
                item['count'] * 100 / report_list.filter(batch__school__name=item['school']).count(), 2)
        return sorted(school_sort, key=lambda x: x['percentage'], reverse=True)

    def get_map_data(self, report_list):
        # 地图分布值
        guangzhou = report_list.filter(batch__school__city=4401) \
            .values('batch__school__district__name') \
            .order_by('batch__school__district__name') \
            .annotate(name=F('batch__school__district__name')) \
            .annotate(value=Count('batch__school__district__name')) \
            .values('name', 'value')
        return guangzhou

    def get_stage_myopia(self, report_list):
        youeryuan_myopia = report_list.filter(stage='幼儿园').count()
        xiaoxue_myopia = report_list.filter(stage='小学').count()
        chuzhong_myopia = report_list.filter(stage='初中').count()
        gaozhong_myopia = report_list.filter(stage='高中').count()
        others_myopia = report_list.filter(stage='其他').count()
        stage_data = [
            {'name': '幼儿园', 'value': youeryuan_myopia},
            {'name': '小学', 'value': xiaoxue_myopia},
            {'name': '初中', 'value': chuzhong_myopia},
            {'name': '高中', 'value': gaozhong_myopia},
            {'name': '其他', 'value': others_myopia},
        ]
        return stage_data

    def get_myopia_data(self, report_list):
        myopia_data = {}
        for index in report_list:
            myopia_data[index.patient_id] = float(index.OS_VASC) < 5.0 or float(index.OD_VASC) < 5.0

        myopia_count = 0
        not_myopia_count = 0
        for _, result in myopia_data.items():
            if result:
                myopia_count += 1
            else:
                not_myopia_count += 1
        myopia_data = [
            {'name': '近视', 'value': myopia_count},
            {'name': '非近视', 'value': not_myopia_count},
        ]
        return myopia_data

    def get_stage_distribution(self):
        # 各类学校总数
        total = Report.objects.filter().count()
        youeryuan = Report.objects.filter(stage='幼儿园').count()
        xiaoxue = Report.objects.filter(stage='小学').count()
        chuzhong = Report.objects.filter(stage='初中').count()
        gaozhong = Report.objects.filter(stage='高中').count()
        others = Report.objects.filter(stage='其他').count()
        school_count = {'total': total,
                        'youeryuan': youeryuan,
                        'xiaoxue': xiaoxue,
                        'chuzhong': chuzhong,
                        'gaozhong': gaozhong,
                        'others': others
                        }
        schoolPieData = [
            {'name': '幼儿园', 'value': youeryuan},
            {'name': '小学', 'value': xiaoxue},
            {'name': '初中', 'value': chuzhong},
            {'name': '高中', 'value': gaozhong},
            {'name': '其他', 'value': others},
        ]
        return school_count, schoolPieData


class PatientView(viewsets.ModelViewSet):
    queryset = Patient.objects.all()
    serializer_class = PatientSerializer
    pagination_class = MyPageNumberPagination

    def perform_create(self, serializer):
        '''
        重写实现保存当前用户为创建者
        '''
        serializer.save(creator=self.request.user)

    @action(methods=['get'], detail=False, url_path='all')
    def get_all(self, request):
        queryset = Patient.objects.filter(status=True)
        query = self.request.query_params.get('keyWord')

        if query:
            queryset = queryset.filter(
                Q(id_card__icontains=query) |
                Q(name__icontains=query) |
                Q(phone__icontains=query))
        serializer = self.get_serializer(queryset, many=True)
        return Response(data=serializer.data)

    def get_queryset(self):
        queryset = super(PatientView, self).get_queryset()
        query = self.request.query_params.get('keyWord')
        is_new = self.request.query_params.get('isNew')
        status = self.request.query_params.get('status')

        if status:
            queryset = queryset.filter(status=status)
        if is_new:
            queryset = queryset.filter(create_time__gte=datetime.now().date())

        if query:
            return queryset.filter(
                Q(id_card__icontains=query) |
                Q(name__icontains=query) |
                Q(phone__icontains=query))
        return queryset

    @action(methods=['POST'], detail=False, url_path='check')
    def check(self, request, *args, **kwargs):
        '''
        检查用户信息是否重复
        '''
        id_card = request.data.get('idCard')
        if id_card and self.queryset.filter(id_card=id_card).exists():
            return Response(status=status.HTTP_406_NOT_ACCEPTABLE)

        return Response(status=status.HTTP_202_ACCEPTED)


class ReportView(viewsets.ModelViewSet):
    '''检查报告'''
    queryset = Report.objects.all()
    serializer_class = ReportSerializer
    pagination_class = MyPageNumberPagination

    # def perform_create(self, serializer):
    #     serializer.save(creator=self.request.user)

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        report_type = self.request.query_params.get('reportType')
        hospital_id = self.request.query_params.get('hospitalId')
        school_id = self.request.query_params.get('schoolId')
        batch_id = self.request.query_params.get('batchId')
        query = self.request.query_params.get('keyWord')
        is_new = self.request.query_params.get('isNew')
        user_id = self.request.query_params.get('userId')
        patientId = self.request.query_params.get('patientId')
        if patientId:
            queryset = queryset.filter(patient=patientId)

        if is_new:
            queryset = queryset.filter(create_time__gte=datetime.now().date())

        if report_type:  # 筛选状态
            queryset = queryset.filter(report_type=report_type)
        if hospital_id:  # 过滤对应医院
            queryset = queryset.filter(batch__hospital=hospital_id)
        if school_id:  # 过滤对应学校
            queryset = queryset.filter(batch__school=school_id)
        if batch_id:  # 过滤对应批次
            queryset = queryset.filter(batch=batch_id)
        if user_id:
            queryset = queryset.filter(user=user_id)

        if query:
            queryset = queryset.filter(
                Q(number__icontains=query) |
                Q(patient__name__icontains=query) |
                Q(batch__school__name__icontains=query) |
                Q(batch__hospital__name__icontains=query))

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)


class BatchView(viewsets.ModelViewSet):
    '''检查批次'''
    queryset = Batch.objects.all()
    serializer_class = BatchSerializer
    pagination_class = MyPageNumberPagination

    @action(methods=['get'], detail=False, url_path='all')
    def get_all_batch(self, request):
        queryset = Batch.objects.all()
        query = self.request.query_params.get('keyWord')

        if query:
            queryset = queryset.filter(
                Q(id_card__icontains=query) |
                Q(name__icontains=query) |
                Q(phone__icontains=query))
        serializer = self.get_serializer(queryset, many=True)
        return Response(data=serializer.data)

    def perform_create(self, serializer):
        serializer.save(creator=self.request.user)

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        query = self.request.query_params.get('keyWord')
        semester = self.request.query_params.get('semester')
        hospital_id = self.request.query_params.get('hopitalId')
        school_id = self.request.query_params.get('schoolId')

        status = self.request.query_params.get('status')
        if status:
            queryset = queryset.filter(status=status)

        if query:
            queryset = queryset.filter(
                Q(number__icontains=query) |
                Q(hospital__name__icontains=query) |
                Q(school__name__icontains=query) |
                Q(semester__icontains=query))
        if semester:
            queryset = queryset.filter(semester=semester)
        if hospital_id:
            queryset = queryset.filter(hospital_id=hospital_id)
        if school_id:  # 过滤对应学校
            queryset = queryset.filter(school=school_id)

        id_list = self.request.data.get("idList")
        if id_list:  # 如果有值，表示导出部分，否则导出全部
            queryset = queryset.filter(id__in=id_list)

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)


class CheckResultView(viewsets.ModelViewSet):
    '''
    自动判断检查的结果
    '''
    queryset = CheckResult.objects.all()
    serializer_class = CheckResultSerializer
